#ifndef ILLIB_EXCEPTION_H_
#define ILLIB_EXCEPTION_H_

#include <stdint.h>


#define assert(expr,...) illib::__assert(__FILE__, __LINE__, (expr),  #expr )


namespace illib{
	void __assert(const char *file, uint32_t line, bool result, const char* expr);

	class Exception{
	private:
		const char * message_;
		Exception();
	public:
		Exception(const char * message) :
			message_(message)
		{

		}
		const char * message(){
			return message_;
		}
	};

	class FatalException : public Exception{
		FatalException();
	protected:
		int code_;
	public:
		FatalException(int code, const char * message) :
			Exception(message),
			code_(code)
		{

		}
	};

	namespace Exceptions{
		class OutOfMemoryException : public FatalException{
		public:
			OutOfMemoryException() : FatalException(1, "Out of memory"){}
		};
		extern OutOfMemoryException memory;

		class OutOfAlignmentException : public FatalException{
		public:
			OutOfAlignmentException() : FatalException(1, "Out of alignment"){}
		};
		extern OutOfAlignmentException alignment;

		class IllegalArguments : public Exception{
		public:
			IllegalArguments() : Exception("Out of alignment"){}
		};
		extern IllegalArguments arguments;

		class IllegalGarbage : public Exception{
		public:
			IllegalGarbage() : Exception("Garbage found"){}
		};
		extern IllegalGarbage garbage;

		class AssertionFailure : public Exception{
		public:
			AssertionFailure() : Exception("Assertion error"){}
		};
		extern AssertionFailure assertion;

		class Unimplemented : public Exception{
		public:
			Unimplemented() : Exception("Unimplemented"){}
		};
		extern Unimplemented unimplemented;
	}
}


#endif /* ILLIB_EXCEPTION_H_ */
